#ifndef WINDOW_H_INCLUDED
#define WINDOW_H_INCLUDED

#include "types.h"

#define glewGetContext() Window::getGLEWContext();

class Window : public Instance
{
    public:
        Window(const string& name = "Untitled", ClassId* classId = sClassId);
        virtual ~Window();

        virtual bool open();
        virtual void close();
        virtual bool isRendering() { return mRendering; }
        virtual void nextFrame();
        virtual void render();

        virtual int getPositionX() { return mPositionX; }
        virtual int getPositionY() { return mPositionY; }
        virtual int getWidth() { return mWidth; }
        virtual int getHeight() { return mHeight; }

        // Event handling
        static void handleEvent(SDL_WindowEvent* event, float dt);
        virtual void onShow(float dt);
        virtual void onHide(float dt);
        virtual void onExpose(float dt);
        virtual void onMove(int dx, int dy, float dt);
        virtual void onResize(int width, int height, float dt);
        virtual void onSizeChange(int width, int height, float dt);
        virtual void onMinimize(float dt);
        virtual void onMaximize(float dt);
        virtual void onRestore(float dt);
        virtual void onEnter(float dt);
        virtual void onLeave(float dt);
        virtual void onFocusGain(float dt);
        virtual void onFocusLose(float dt);
        virtual void onClose(float dt);

        // Instance
        DECLARE_CLASSID(Window);
        virtual bool load(DataStream* ds = 0);
        virtual bool save(DataStream* ds = 0);

        // GLEW context
        static GLEWContext* getGLEWContext();
        static map<Uint32,GLEWContext*> sGLEWContextMap;

        // SDL WindowID => Window*
        static Window* getFromId(Uint32 windowId);

    protected:
        friend class ZenDjinn;
        static map<Uint32,Window*> sIdMap;
        static SDL_mutex* sIdMapMutex;

    private:
        static int renderThread(void* data);
        SDL_Thread* mRenderThread;
        SDL_sem* mRenderSem;
        bool mRendering;
        SDL_Window* mWindow;
        SDL_GLContext mGLContext;
        Uint32 mFlags;
        int mPositionX, mPositionY;
        int mWidth, mHeight;
};

#endif // WINDOW_H_INCLUDED
